package com.fita.wechat.web.controller;

import java.util.Map;

import javax.servlet.http.HttpServletRequest;

import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;

import com.demo2do.core.entity.exception.BusinessException;
import com.demo2do.core.entity.result.HttpResult;
import com.demo2do.core.utils.JsonUtils;
import com.fita.entity.order.Order;
import com.fita.entity.order.PaymentRequest;
import com.fita.wechat.service.PaymentCallbackService;

/**
 * 
 * @author mohanlan
 *
 */
@RestController
@RequestMapping("/payment")
public class PaymentRestController {
    
    private static final Logger logger = LoggerFactory.getLogger(PaymentRestController.class);
    
    @Autowired
    private PaymentCallbackService paymentCallbackService;
    
    @RequestMapping(value = "/callback", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    public @ResponseBody HttpResult onPaid(@RequestBody String body,
            HttpServletRequest request) {
        
        Map<String, Object> params = JsonUtils.parse(body);
        
        logger.info("#onPaid - Get rquest number [{}], order number [{}], amount [{}], pay time [{}], channel [{}].", 
                params.get("requestNo"), params.get("orderNo"), params.get("transactionCode"), params.get("amount"), params.get("paymentTime"));
        
        HttpResult httpResult = new HttpResult();
        
        try {
            
            String requestCode = params.get("requestNo").toString();
            
            PaymentRequest paymentRequest = paymentCallbackService.load(requestCode);
            
            // validate payment request
            if(paymentRequest == null) {
                throw new BusinessException("支付回调数据错误");
            }
            
            // validate payment request & order code
            String orderCode = params.get("orderNo").toString();
            if(!StringUtils.equalsIgnoreCase(orderCode, paymentRequest.getOrderCode())) {
                throw new BusinessException("支付回调数据异常");
            }
            
            // do pay order
            String payCode = params.get("transactionCode").toString();
            String payTime = params.get("paymentTime").toString();
            int amount = Integer.parseInt(params.get("amount").toString());
            
            Order order = paymentCallbackService.pay(paymentRequest, orderCode, payCode, payTime, amount);
            
            // TODO call api
            
            httpResult.success()
                      .message("支付回调成功")
                      .data("order", order);
            
            // check order & update order, product things
            logger.info("#onPaid() - Synchronizing order with result [{}] !!!!!!!!", httpResult.getMessage());
            
        } catch (BusinessException e) {
            httpResult.fail("500").message(e.getMessage());
        } catch (Exception e) {
            logger.error("#prepare - occurs error", e);
            httpResult.fail("500").message("请求支付数据失败");
        }
        
        return httpResult;
    }
}
